------------------------------------------------------------
-- Recipients
--
-- Creates a drop down list for mail recipients.
-- Keeps last recipient name in the SendMailNameEditBox.
--
-- Abin
-- 2007-11-20
------------------------------------------------------------

local VERSION = "1.01";
local L = RECIPIENTS_LOCALE;
local LIST_MAX = 49; -- maximum number of the list
local db = nil;
local curName = nil;
local curSel = nil;
local lastRecipient = nil;
local Orig_SendMail = SendMail;

------------------------------------------------------------
-- Internal Functions
------------------------------------------------------------

-- Prints a message
local function PrintMessage(msg)
	DEFAULT_CHAT_FRAME:AddMessage("|cffffff78"..L["title"]..":|r "..tostring(msg))
end

-- Obtains recipient name through hooking SendMail
local function Hooked_SendMail(name, subject, body)
	lastRecipient = name;
	Orig_SendMail(name, subject, body);
end

-- Gets recipient name from SendMailNameEditBox
local function GetEditBoxString()
	local name = SendMailNameEditBox:GetText();
	name = string.trim(name or "");
	if name == "" then
		name = nil;
	end
	return name;
end

-- Finds a name from list
local function ListFind(name)
	if type(name) ~= "string" or name == "" then
		return nil;
	end

	local str = string.lower(name);
	local i;
	for i = 1, table.getn(db) do
		if string.lower(db[i]) == str then
			return i;
		end
	end
	return nil;
end

-- Sets a check mark for the currently selected name
local function ListSelect()
	curSel = this.value;
	if type(curSel) == "number" and curSel > 0 and type(db[curSel]) == "string" then
		curName = db[curSel];
		SendMailNameEditBox:SetText(curName);
		SendMailNameEditBox:HighlightText(0, -1);
		SendMailSubjectEditBox:SetFocus();
	end
end

-- Adds a new name into the list
local function ListAdd()
	if curName and curName ~= "" then
		if table.getn(db) < LIST_MAX then
			table.insert(db, curName);
			table.sort(db);
			curSel = ListFind(curName);
			SendMailNameEditBox:SetText(curName);
			SendMailNameEditBox:HighlightText(0, -1);
			SendMailSubjectEditBox:SetFocus();
			PrintMessage(string.format(L["name added"], curName));
		else
			PrintMessage(L["full"]);
		end
	end
end

-- Removes a name from the list
local function ListRemove()
	local idx = ListFind(curName);
	if idx then
		table.remove(db, idx);		
		SendMailNameEditBox:SetText("");
		SendMailNameEditBox:SetFocus();
		PrintMessage(string.format(L["name removed"], curName));
		curName = nil;
		curSel = nil;		
	end	
end

-- Populates our drop down list
local function ListDropdownInit()
	local header = false;
	local info = { value = 0, notCheckable = 1 };
	curName = GetEditBoxString();
	if curName then	
		-- Operations
		if ListFind(curName) then
			-- Remove existing name
			info.text = L["remove"]..curName;
			info.func = function() ListRemove(); end
			UIDropDownMenu_AddButton(info);
			header = true;
		else
			-- Add new name
			info.text = L["add"]..curName;
			info.func = function() ListAdd(); end
			UIDropDownMenu_AddButton(info);
			header = true;
		end
	end

	if header and table.getn(db) > 0 then
		-- Inserts a blank line between operation header and name list
		info = { value = 0, isTitle = 1, textHeight = 1 };
		UIDropDownMenu_AddButton(info);
	end

	local i;
	for i = 1, table.getn(db) do
		if i <= LIST_MAX then
			info = { text = db[i], value = i, func = function() ListSelect(); end };
			if i == curSel then
				info.checked = 1;
			end
			UIDropDownMenu_AddButton(info);
		end
	end	
end

------------------------------------------------------------
-- Global Functions
------------------------------------------------------------

-- UI handler: OnLoad
function Recipients_OnLoad()
	SendMail = function(name, subject, body) Hooked_SendMail(name, subject, body); end
	this:RegisterEvent("VARIABLES_LOADED");
	this:RegisterEvent("MAIL_SEND_SUCCESS");
	this:RegisterEvent("MAIL_FAILED");
	PrintMessage(VERSION.." by 1.0 loaded.");
end

-- UI handler: OnEvent
function Recipients_OnEvent()
	if event == "VARIABLES_LOADED" then
		local profile = (GetRealmName() or "SF").."-"..(UnitFactionGroup("player") or "Default");
		if type(RecipientsDB) ~= "table" then
			RecipientsDB = {};
		end

		if type(RecipientsDB[profile]) ~= "table" then
			RecipientsDB[profile] = {};
		end

		db = RecipientsDB[profile];
	elseif event == "MAIL_SEND_SUCCESS" or event == "MAIL_FAILED" then
		-- After the mail is sent, puts back last name into SendMailNameEditBox
		if SendMailNameEditBox:IsShown() and lastRecipient and lastRecipient ~= "" then
			SendMailNameEditBox:SetText(lastRecipient);
			SendMailSubjectEditBox:SetFocus();
		end
	end
end

-- UI handler: OnShow
function Recipients_OnShow()
	curName = nil;
	curSel = nil;
	UIDropDownMenu_Initialize(this:GetParent(), function() ListDropdownInit(); end);
	UIDropDownMenu_SetAnchor(-12, 0, this:GetParent(), "TOPLEFT", SendMailNameEditBox, "BOTTOMLEFT");
end

-- UI handler: OnEnter
function Recipients_OnEnter()
	-- Shows game tooltip when mouse hovers over our button
	GameTooltip:SetOwner(this, "ANCHOR_RIGHT");
	GameTooltip:ClearLines();
	GameTooltip:SetText(L["title"]);
	local count = table.getn(db);
	GameTooltip:AddLine(string.format(L["count"], count));
	if count > 0 or GetEditBoxString() then
		GameTooltip:AddLine(L["click open"]);
	else
		GameTooltip:AddLine(L["empty prompt"]);
	end
	GameTooltip:Show();
end